Select and copy text in the viewer - #859
Merged
Merged
Conversation
Every pane was owner drawn with no selection anywhere in the model, so the one thing a reader wants to do with a failing snapshot - take the text somewhere else - could not be done at all. Drag across either pane to select, ctrl+c to copy, ctrl+a to select one side. Every entry's context menu also offers Copy selection, and a Copy item per pane that has anything in it. A drag arrives from a head as both of its ends at once, reported on every frame the button is held rather than as press, move and release events: the managed side already holds the selection by then, so a release has nothing to add, and a whole press-drag-release landing inside one frame still arrives whole. Rows are rows of the whole side rather than of the visible slice, because a head knows the scroll top it drew the press with and is the only thing that can resolve a drag spanning a wheel notch. A selection names the entry it was dragged in, so one left behind by an accept, a discard or a variant cycle stops existing rather than needing a clear on every transition - one of which would eventually be missed. AsciiRenderer draws a fixed width character grid and has no way to invert part of a line without changing its width, so what the model universally states about a selection goes in the status line, where every renderer draws it and the text snapshots show it, and the highlight is the enrichment the three pixel heads paint on top. The same bargain ImagePane already makes. Copying is IViewerWindow.SetClipboard rather than a ViewerActions member, because a clipboard belongs to a toolkit the way a window does: WinForms, AppKit and GLFW each own one, and the alternative was shelling out to clip, pbcopy and whichever of xclip or wl-copy happened to be installed. It is answered before the owner link, since the text is already in this process and an owner's answer would be a round trip to fetch what this one is holding. Keys.A was matched ignoring modifiers in all three heads, so ctrl+a would have accepted the snapshot rather than selecting it. DEVIEW_VERSION goes to 8: DeviewRow carries the selected run and DeviewInput the drag, with deview_set_clipboard beside them. DeviewRow is a widened array element, so this is the same kind of bump 6 was and the binaries have to be rebuilt with it. The missing note for 7 is backfilled while here. PixelTests.Selection has no Linux or macOS baseline yet; those come out of the pixel job's received artifacts once the rebuilt binaries land.
Co-authored-by: SimonCropp <122666+SimonCropp@users.noreply.github.com>
The two Selection captures are new, and the Linux context menu grew the two copy items the ASCII snapshot and the WinForms one already show. All three came out of the pixel jobs' received artifacts, which is where a baseline for a renderer this machine cannot run has to come from.
This was referenced Aug 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every pane was owner drawn with no selection anywhere in the model, so the one thing a reader wants to do with a failing snapshot — take the text somewhere else — could not be done at all.
Drag across either pane to select,
ctrl+cto copy,ctrl+ato select one side. Every entry's context menu also offers Copy selection, and a Copy item per pane that has anything in it — a pending delete's left side is the state after accepting, which is no file, so it gets no item rather than one that reports having copied nothing.A drag arrives from a head as both of its ends at once, reported on every frame the button is held rather than as press, move and release events. The managed side is already holding the selection by then, so a release has nothing to add, and a whole press-drag-release landing inside one frame still arrives whole. Rows are rows of the whole side rather than of the visible slice, because a head knows the scroll top it drew the press with and is the only thing that can resolve a drag spanning a wheel notch.
A selection names the entry it was dragged in, so one left behind by an accept, a discard or a variant cycle stops existing rather than needing a clear on every transition — one of which would eventually be missed.
AsciiRendererdraws a fixed width character grid and has no way to invert part of a line without changing its width. So what the model universally states about a selection goes in the status line, where every renderer draws it and the text snapshots show it, and the highlight is the enrichment the three pixel heads paint on top. The same bargainImagePanealready makes.Copying is
IViewerWindow.SetClipboardrather than aViewerActionsmember, because a clipboard belongs to a toolkit the way a window does: WinForms, AppKit and GLFW each own one, and the alternative was shelling out toclip,pbcopyand whichever ofxcliporwl-copyhappened to be installed. It is answered before the owner link, since the text is already in this process and an owner's answer would be a round trip to fetch what this one is holding.Keys.Awas matched ignoring modifiers in all three heads, soctrl+awould have accepted the snapshot rather than selecting it.ABI
DEVIEW_VERSIONgoes to 8:DeviewRowcarries the selected run of its text andDeviewInputreports a drag across a pane, withdeview_set_clipboardbeside them.DeviewRowis a widened array element, so this is the same kind of bump 6 was. The rebuilt binaries are already on this branch, from #858. The missing note for 7 is backfilled while here.One expected failure
PixelTests.Selectionis new and has no Linux or macOS baseline yet. Both pixel jobs will fail on it and upload the images asreceived-*artifacts, which is where those two baselines come from.WindowsPixelTests.Selectionis committed, andPaneHitTestscloses the loop the other way: it draws a selection, finds the pixels it landed on and feeds them back through the hit test. That is the only check that the painter and the hit test are reading one layout — the pixel snapshots show where a highlight went and say nothing about where a click resolves to.